UNPKG

@cosmology/ast

Version:
166 lines (142 loc) 4.72 kB
import * as t from '@babel/types'; import { ProtoField, ProtoType } from '@cosmology/types'; import { AminoParseContext } from '../../context'; import { getTypeUrl, protoFieldsToArray, getAminoTypeName } from '../utils'; import { aminoInterface } from './utils'; import { getFieldOptionality, getOneOfs } from '../../proto'; export interface RenderAminoField { context: AminoParseContext; field: ProtoField; currentProtoPath: string; isOptional: boolean; }; export const renderAminoField = ({ context, field, currentProtoPath, isOptional }: RenderAminoField) => { const args = { context, field, currentProtoPath, isOptional } if (field.rule === 'repeated') { switch (field.parsedType.type) { case 'Type': return aminoInterface.typeArray(args); case 'Enum': return aminoInterface.enumArray(args); default: return aminoInterface.array(args); } } // special "native" types... // above Type,Enum since they're Types switch (field.type) { // TODO check can we just // make pieces optional and avoid hard-coding this type? case 'ibc.core.client.v1.Height': case 'Height': return aminoInterface.height(args); case 'Timestamp': case 'google.protobuf.Timestamp': return aminoInterface.timestamp(args); case 'Duration': case 'google.protobuf.Duration': return aminoInterface.duration(args); case 'Any': case 'google.protobuf.Any': switch (field.options?.['(cosmos_proto.accepts_interface)']) { case 'cosmos.crypto.PubKey': return aminoInterface.pubkey(args); } } switch (field.parsedType.type) { case 'Type': return aminoInterface.type(args); case 'Enum': return aminoInterface.enum(args); } // scalar types... switch (field.type) { case 'string': return aminoInterface.defaultType(args); case 'int64': case 'sint64': case 'uint64': case 'fixed64': case 'sfixed64': return aminoInterface.long(args); case 'double': case 'bool': case 'bytes': case 'int32': case 'sint32': case 'uint32': case 'fixed32': case 'sfixed32': return aminoInterface.defaultType(args); // // TODO check can we just // // make pieces optional and avoid hard-coding this type? // case 'ibc.core.client.v1.Height': // case 'Height': // return aminoInterface.height(args); // case 'Timestamp': // case 'google.protobuf.Timestamp': // return aminoInterface.timestamp(args); // case 'Duration': // case 'google.protobuf.Duration': // return aminoInterface.duration(args); default: return aminoInterface.defaultType(args); } }; export interface MakeAminoTypeInterface { context: AminoParseContext; proto: ProtoType; }; export const makeAminoTypeInterface = ({ context, proto }: MakeAminoTypeInterface) => { context.addUtil('AminoMsg'); const TypeName = proto.name; const aminoType = getAminoTypeName(context, context.ref.proto, proto); const oneOfs = getOneOfs(proto); const fields = protoFieldsToArray(proto).map((field) => { const isOneOf = oneOfs.includes(field.name); const isOptional = getFieldOptionality(context, field, isOneOf); const aminoField = renderAminoField({ context, field, currentProtoPath: context.ref.filename, isOptional }); return { ctx: context, field: aminoField } }); const annotation = !context.options.aminoEncoding.useLegacyInlineEncoding ? t.tsTypeAnnotation(t.tsTypeReference( t.identifier(TypeName + 'Amino') )) : t.tsTypeAnnotation(t.tsTypeLiteral( fields.map(({ field }) => field) )); return t.exportNamedDeclaration( t.tsInterfaceDeclaration( t.identifier(TypeName + 'AminoType'), null, [t.tsExpressionWithTypeArguments(t.identifier('AminoMsg'))], t.tSInterfaceBody([ t.tSPropertySignature(t.identifier('type'), t.tsTypeAnnotation( t.tSLiteralType(t.stringLiteral(aminoType)) )), t.tSPropertySignature(t.identifier('value'), annotation) ]) ) ) }