blob: 3e11dee25c6916d0c65853b7898d5ed56e0aa9c3 [file] [log] [blame]
Jens Geyer72a714e2025-08-26 22:12:07 +02001#
2# Licensed to the Apache Software Foundation (ASF) under one
3# or more contributor license agreements. See the NOTICE file
4# distributed with this work for additional information
5# regarding copyright ownership. The ASF licenses this file
6# to you under the Apache License, Version 2.0 (the
7# "License"); you may not use this file except in compliance
8# with the License. You may obtain a copy of the License at
Eric Connerc34653f2017-06-21 03:34:12 +02009#
10# http://www.apache.org/licenses/LICENSE-2.0
11#
Jens Geyer72a714e2025-08-26 22:12:07 +020012# Unless required by applicable law or agreed to in writing,
13# software distributed under the License is distributed on an
14# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15# KIND, either express or implied. See the License for the
16# specific language governing permissions and limitations
17# under the License.
18#
Eric Connerc34653f2017-06-21 03:34:12 +020019
Eric Connerc34653f2017-06-21 03:34:12 +020020from thrift.Thrift import TType
21
22TYPE_IDX = 1
23SPEC_ARGS_IDX = 3
24SPEC_ARGS_CLASS_REF_IDX = 0
25SPEC_ARGS_THRIFT_SPEC_IDX = 1
26
27
28def fix_spec(all_structs):
29 """Wire up recursive references for all TStruct definitions inside of each thrift_spec."""
30 for struc in all_structs:
31 spec = struc.thrift_spec
32 for thrift_spec in spec:
33 if thrift_spec is None:
34 continue
35 elif thrift_spec[TYPE_IDX] == TType.STRUCT:
36 other = thrift_spec[SPEC_ARGS_IDX][SPEC_ARGS_CLASS_REF_IDX].thrift_spec
37 thrift_spec[SPEC_ARGS_IDX][SPEC_ARGS_THRIFT_SPEC_IDX] = other
38 elif thrift_spec[TYPE_IDX] in (TType.LIST, TType.SET):
39 _fix_list_or_set(thrift_spec[SPEC_ARGS_IDX])
40 elif thrift_spec[TYPE_IDX] == TType.MAP:
41 _fix_map(thrift_spec[SPEC_ARGS_IDX])
42
43
44def _fix_list_or_set(element_type):
Eric Connerb56ead32017-07-06 21:38:05 -070045 # For a list or set, the thrift_spec entry looks like,
Eric Connerc34653f2017-06-21 03:34:12 +020046 # (1, TType.LIST, 'lister', (TType.STRUCT, [RecList, None], False), None, ), # 1
47 # so ``element_type`` will be,
48 # (TType.STRUCT, [RecList, None], False)
49 if element_type[0] == TType.STRUCT:
50 element_type[1][1] = element_type[1][0].thrift_spec
51 elif element_type[0] in (TType.LIST, TType.SET):
52 _fix_list_or_set(element_type[1])
53 elif element_type[0] == TType.MAP:
54 _fix_map(element_type[1])
55
56
57def _fix_map(element_type):
58 # For a map of key -> value type, ``element_type`` will be,
59 # (TType.I16, None, TType.STRUCT, [RecMapBasic, None], False), None, )
60 # which is just a normal struct definition.
61 #
62 # For a map of key -> list / set, ``element_type`` will be,
63 # (TType.I16, None, TType.LIST, (TType.STRUCT, [RecMapList, None], False), False)
64 # and we need to process the 3rd element as a list.
Eric Connerb56ead32017-07-06 21:38:05 -070065 #
Eric Connerc34653f2017-06-21 03:34:12 +020066 # For a map of key -> map, ``element_type`` will be,
Eric Connerb56ead32017-07-06 21:38:05 -070067 # (TType.I16, None, TType.MAP, (TType.I16, None, TType.STRUCT,
Eric Connerc34653f2017-06-21 03:34:12 +020068 # [RecMapMap, None], False), False)
69 # and need to process 3rd element as a map.
70
71 # Is the map key a struct?
72 if element_type[0] == TType.STRUCT:
73 element_type[1][1] = element_type[1][0].thrift_spec
74 elif element_type[0] in (TType.LIST, TType.SET):
75 _fix_list_or_set(element_type[1])
76 elif element_type[0] == TType.MAP:
77 _fix_map(element_type[1])
78
79 # Is the map value a struct?
80 if element_type[2] == TType.STRUCT:
81 element_type[3][1] = element_type[3][0].thrift_spec
82 elif element_type[2] in (TType.LIST, TType.SET):
83 _fix_list_or_set(element_type[3])
84 elif element_type[2] == TType.MAP:
85 _fix_map(element_type[3])